/*
 ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1

 * The contents of this file are subject to the Mozilla Public License Version 
 * 1.1 (the "License"); you may not use this file except in compliance with 
 * the License. You may obtain a copy of the License at 
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Blazing Games Inc. (Billy D. Spelchan) code.
 *
 * The Initial Developer of the Original Code is
 * Blazing Games Inc.
 * Portions created by the Initial Developer are Copyright (C) 1999, 2003, 2005-2006
 * the Initial Developer. All Rights Reserved.
 * 
 * Contributor(s):
 *
 ***** END LICENSE BLOCK *****
 */
package com.blazinggames.holeman;

import java.awt.*;
import java.awt.event.*;
//import java.util.*;

public class HolemanFrame
extends Frame
implements ActionListener, ItemListener {
// *** CONSTANTS ***
  // screen modes
  public static final int SCREEN_GAME = 1;
  public static final int SCREEN_TEST = 2;
  public static final int SCREEN_EDIT = 3;

  private static boolean INJAR = false;

// *** VARIABLES ***
  Map map;
  GameScreen gameScreen;
  LevelList listScreen;
  Construct constructScreen;

CheckboxMenuItem cmiSmall, cmiLarge;
  CheckboxMenuItem cmiFast, cmiNormal, cmiSlow, cmiSlowest;

  int nCurrentSize;

  FileDialog fdSave, fdOpen;
  /**
    The constructor class.  Adjusts the windows size and title, creates
    the menu bar, then enables the close window event.
  */
	public HolemanFrame() {
    map = new Map();

	  // Make menu bar.
    initMenus();

    // Set up the window
    setTitle("Mr. Holeman - the application version");
    setResizable(false);

    gameScreen = new GameScreen(map, this, getClass(), null, INJAR);
    gameScreen.screenHigh(INJAR);
    listScreen = new LevelList(this);
    constructScreen = new Construct(map, this);

    listScreen.refreshList(map);

    setLayout(new CardLayout());
    add("list", listScreen);
    add("cons", constructScreen);
    add("game", gameScreen);

    // Make it possible to close the window
    enableEvents(WindowEvent.WINDOW_CLOSING);
	}

  /*
    Create the menus for the window
  */
  private void initMenus() {
    MenuBar mb = new MenuBar();
    // FILE menu
    Menu m = new Menu("File");
    MenuItem mi = new MenuItem("New");
    mi.addActionListener(this);
    m.add(mi);
    mi = new MenuItem("Open Set...");
    mi.addActionListener(this);
    m.add(mi);
    mi = new MenuItem("Save Set");
    mi.addActionListener(this);
    m.add(mi);
    mi = new MenuItem("Save Set As...");
    mi.addActionListener(this);
    m.add(mi);
    mi = new MenuItem("-");
    m.add(mi);
    mi = new MenuItem("Quit");
    mi.addActionListener(this);
    m.add(mi);
    mi = new MenuItem("List");
    mi.addActionListener(this);
    m.add(mi);
    mb.add( m );

    // SIZE menu
    m = new Menu("Size");
    cmiSmall = new CheckboxMenuItem("Small", false);
    cmiSmall.addItemListener(this);
    m.add(cmiSmall);
    nCurrentSize = 1;
    cmiLarge = new CheckboxMenuItem("Large", true);
    cmiLarge.addItemListener(this);
    m.add(cmiLarge);
    mb.add(m);

    // Speed menu
    m = new Menu("Speed");
    cmiFast = new CheckboxMenuItem("Fast", true);
    cmiFast.addItemListener(this);
    m.add(cmiFast);
    cmiNormal = new CheckboxMenuItem("Normal", false);
    cmiNormal.addItemListener(this);
    m.add(cmiNormal);
    cmiSlow = new CheckboxMenuItem("Slow", false);
    cmiSlow.addItemListener(this);
    m.add(cmiSlow);
    cmiSlowest = new CheckboxMenuItem("Slowest", false);
    cmiSlowest.addItemListener(this);
    m.add(cmiSlowest);
    mb.add(m);
    setMenuBar( mb );
  }

  public void doLayout() {
    int nW, nH;
    if (nCurrentSize == 0) {
      nW = 320;
      nH = 220;
    }
    else {
      nW = 640;
      nH = 440;
    }

    Insets insets = getInsets();
    if ( ((nW+insets.left+insets.right) != getSize().width) ||
          ((nH+insets.top+insets.bottom) != getSize().height) ){
      System.out.println("AdJusting size");
      setSize(new Dimension(nW+insets.left+insets.right, nH+insets.top+insets.bottom));
    }
    super.doLayout();
  }

  private void changeScreen(int nID, int nLevel) {
    System.gc();
    switch (nID) {
      case SCREEN_GAME:
        map.startLevel(nLevel);
        gameScreen.setTest(false);
        ((CardLayout)getLayout()).show(this, "game");
          gameScreen.requestFocus();
        break;
      case SCREEN_TEST:
        map.startLevel(nLevel);
        gameScreen.setTest(true);
        ((CardLayout)getLayout()).show(this, "game");
          gameScreen.requestFocus();
        break;
      case SCREEN_EDIT:
        constructScreen.setLevel(nLevel);
        ((CardLayout)getLayout()).show(this, "cons");
        break;
    }
  }

  private void menu_FileNew() {
    map.newSet();
    listScreen.refreshList(map);
    ((CardLayout)getLayout()).show(this, "list");
    fdSave = null;
  }

  private void menu_FileOpen() {
    if (fdOpen == null)
      fdOpen = new FileDialog(this, "Select Set to Open", FileDialog.LOAD);
    fdOpen.show();
    if (fdOpen.getFile() != null) {
      System.out.println("Open file: " + fdOpen.getDirectory() + fdOpen.getFile());
      map.loadSet(fdOpen.getDirectory() + fdOpen.getFile());
      listScreen.refreshList(map);
      ((CardLayout)getLayout()).show(this, "list");
      fdSave = null;
    }
  }

  private void menu_FileSave() {
    if (fdSave == null) {
      menu_FileSaveAs();
      return;
    }
    if (fdSave.getFile() == null) {
      menu_FileSaveAs();
      return;
    }
    System.out.println("Save file: " + fdSave.getDirectory() + fdSave.getFile());
    map.saveSet(fdSave.getDirectory() + fdSave.getFile());
    listScreen.refreshList(map);
    ((CardLayout)getLayout()).show(this, "list");
  }

  private void menu_FileSaveAs() {
    if (fdSave == null)
      fdSave = new FileDialog(this, "Save set as", FileDialog.SAVE);
    fdSave.show();
    if (fdSave.getFile() != null) {
      System.out.println("Save file as: " + fdSave.getDirectory() + fdSave.getFile());
      map.saveSet(fdSave.getDirectory() + fdSave.getFile());
      listScreen.refreshList(map);
      ((CardLayout)getLayout()).show(this, "list");
    }
  }

  /**
    Handle menu events (well, the quit option) and Panel actions.
  */
	public void actionPerformed(ActionEvent e) {
		String sID = e.getActionCommand();

    // If selected menu is Quit
    if (sID.equals("New") )
      menu_FileNew();
    else if ( sID.equals( "Open Set..." ) )
      menu_FileOpen();
    else if ( sID.equals( "Save Set" ) )
      menu_FileSave();
    else if ( sID.equals( "Save Set As..." ) )
      menu_FileSaveAs();
    else if ( sID.equals( "Quit" ) ) {
      setVisible(false);
      dispose();
      System.exit(0);
    }
    else if ( (sID.equals("List")) || (sID.equals("Next")) ||
          (sID.equals("Killed")) || (sID.equals("GameOver")) ||
          (sID.equals("Reset")) )
        ((CardLayout)getLayout()).show(this, "list");
    else {
      String sCmd = sID.substring(0, 4);

      if (sCmd.equals("Capt")) {
        InfoEdit ld = new InfoEdit(this);
        ld.setInfo(map, Integer.parseInt(sID.substring(4)));
        ld.show();
        ld.updateMapInfo(map, Integer.parseInt(sID.substring(4)));
        ld.dispose();
        listScreen.refreshList(map);
      }
      else if (sCmd.equals("Edit"))
        changeScreen(SCREEN_EDIT, Integer.parseInt(sID.substring(4)));
      else if (sCmd.equals("Test") )
        changeScreen(SCREEN_TEST, Integer.parseInt(sID.substring(4)));
      else if (sCmd.equals("Play") )
        changeScreen(SCREEN_GAME, Integer.parseInt(sID.substring(4)));
      else
        System.out.println("Unknown command: " + sID);
    }
  }

  public void itemStateChanged(ItemEvent e) {
		ItemSelectable sID = e.getItemSelectable();

    // SIZE MENU
    if ( sID == cmiSmall ) {
      if (nCurrentSize != 0) {
        gameScreen.screenLow(getClass(), INJAR);
        constructScreen.screenLow();
      }
      nCurrentSize = 0;
      cmiSmall.setState(true);
      cmiLarge.setState(false);
      doLayout();
    }
    else if ( sID == cmiLarge ) {
      if (nCurrentSize != 1) {
        gameScreen.screenHigh(INJAR);
        constructScreen.screenHigh();
      }
      nCurrentSize = 1;
      cmiSmall.setState(false);
      cmiLarge.setState(true);
      doLayout();
    }
    // SPEED MENU
    else if (sID == cmiFast)
      setSpeed(1);
    else if (sID == cmiNormal)
      setSpeed(2);
    else if (sID == cmiSlow)
      setSpeed(3);
    else if (sID == cmiSlowest)
      setSpeed(4);
  }

  private void setSpeed(int n) {
    cmiFast.setState(false);
    cmiNormal.setState(false);
    cmiSlow.setState(false);
    cmiSlowest.setState(false);
    map.setDelay(n);
    switch(n) {
      case 1:
        cmiFast.setState(true);
        break;
      case 2:
        cmiNormal.setState(true);
        break;
      case 3:
        cmiSlow.setState(true);
        break;
      case 4:
        cmiSlowest.setState(true);
        break;
    }
  }

  /**
   Handle closing of the window
  */
  protected void processEvent(AWTEvent e) {
    // See of window being closed
    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
      setVisible(false);
      dispose();
      System.exit(0);
    }
    // if not let java handle the event
    super.processEvent(e);
  }

}

